package com.bootdo.system.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.bootdo.common.utils.R;
import com.bootdo.system.alipayUtil.AlipayConfig;
import com.bootdo.system.domain.OrderDO;
import com.bootdo.system.domain.SceneryOrderDO;
import com.bootdo.system.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;


@RequestMapping("/alipay")
@Controller
public class AlipayController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private OrderService orderService;

    @PostMapping("/saveOrder")
    @ResponseBody
    public R saveOrder(OrderDO orderDO) {
        String orderNo=getOrderIdByTime();
        orderDO.setOrderNo(orderNo);
        //支付宝
        orderDO.setPayType("1");
        //还未支付
        orderDO.setStatus("3");
        if(orderService.save(orderDO)>0){
            return R.ok().put("orderNo",orderNo).put("totalAmount",orderDO.getPayMoney());
        }
        return R.error();
    }


    @RequestMapping("/get_qr_code")
    public   void   doPost (HttpServletRequest httpRequest,
                            HttpServletResponse httpResponse)   throws ServletException, IOException {
        /** 初始化 **/
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        /** 支付宝网关 **/
        certAlipayRequest.setServerUrl(AlipayConfig.gatewayUrl);
        /** 应用id，如何获取请参考：https://opensupport.alipay.com/support/helpcenter/190/201602493024 **/
        certAlipayRequest.setAppId(AlipayConfig.app_id);
        /** 应用私钥, 如何获取请参考：https://opensupport.alipay.com/support/helpcenter/207/201602471154?ant_source=antsupport  **/
        certAlipayRequest.setPrivateKey(AlipayConfig.merchant_private_key);
        /** 应用公钥证书路径，下载后保存位置的绝对路径  **/
        //C:/CSR/appCertPublicKey_2016110100784886.crt
        certAlipayRequest.setCertPath(AlipayConfig.certPath);
        /** 支付宝公钥证书路径，下载后保存位置的绝对路径 **/
        certAlipayRequest.setAlipayPublicCertPath(AlipayConfig.alipayPublicCertPath);
        /** 支付宝根证书路径，下载后保存位置的绝对路径 **/
        certAlipayRequest.setRootCertPath(AlipayConfig.rootCertPath);
        /** 设置签名类型 **/
        certAlipayRequest.setSignType(AlipayConfig.sign_type);
        /** 设置请求格式，固定值json **/
        certAlipayRequest.setFormat("json");
        /** 设置编码格式 **/
        certAlipayRequest.setCharset(AlipayConfig.charset);
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(certAlipayRequest);
        } catch (AlipayApiException e1) {
            e1.printStackTrace();
        }
        /** 实例化具体API对应的request类，类名称和接口名称对应,当前调用接口名称：alipay.fund.trans.uni.transfer(单笔转账接口) **/
        AlipayTradePagePayRequest alipayRequest =  new  AlipayTradePagePayRequest(); //创建API对应的request
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url ); //在公共参数中设置回跳和通知地址
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(httpRequest.getParameter("orderNo"));
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        model.setSubject("网上订票");
        model.setTotalAmount(httpRequest.getParameter("totalAmount"));
        model.setBody("订单描述");
        alipayRequest.setBizModel(model);
        String form= "" ;
        try  {
            form = alipayClient.pageExecute(alipayRequest).getBody();  //调用SDK生成表单
        }  catch  (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType( "text/html;charset="  + AlipayConfig.charset);
        httpResponse.getWriter().write(form); //直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }


    public static String getOrderIdByTime() {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
        String newDate=sdf.format(new Date());
        String result="";
        Random random=new Random();
        for(int i=0;i<3;i++){
            result+=random.nextInt(10);
        }
        return newDate+result;
    }

    @PostMapping("/notify")
    @ResponseBody
    public String pay_notify(HttpServletRequest request,HttpServletResponse response) {
        Map<String, String> paramsMap = convertRequestParamsToMap(request);
        String out_trade_no= paramsMap.get("out_trade_no");
        String trade_status= paramsMap.get("trade_status");
        try {
            //验签方法
            boolean signVerified= AlipaySignature.rsaCertCheckV1(paramsMap, AlipayConfig.alipayPublicCertPath,AlipayConfig.charset, AlipayConfig.sign_type);
            System.out.println("异步signVerified"+signVerified);
            //无论同步异步都要验证签名
            if(signVerified){
                if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")){
                    //处理自己系统的业务逻辑，如：将支付记录状态改为成功，需要返回一个字符串success告知支付宝服务器
                    System.out.println("success");
                    return "异步 success";
                } else {
                    //支付失败不处理业务逻辑
                    return "failure";
                }
            }else {
                //签名验证失败不处理业务逻辑
                return "failure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "failure";
        }
    }


    @GetMapping("/return")
    public String pay_return(HttpServletRequest request,Model model) {
        System.out.println("支付完成进入同步通知"+request.getParameterMap());
        Map<String, String> paramsMap = convertRequestParamsToMap(request);
        try {
            //验签方法
            boolean signVerified= AlipaySignature.rsaCertCheckV1(paramsMap, AlipayConfig.alipayPublicCertPath,AlipayConfig.charset, AlipayConfig.sign_type);
            //验签方法
            System.out.println("signVerified"+signVerified);
            if(signVerified){
                //跳转支付成功界面
                return "shibanhe/success_pay";
            }else {
                //跳转支付失败界面
                return "shibanhe/fail_pay";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "shibanhe/fail_pay";
    }



    //将请求中的参数转换为Map
    public static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap();
        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
        Iterator var3 = entrySet.iterator();

        while(true) {
            while(var3.hasNext()) {
                Map.Entry<String, String[]> entry = (Map.Entry)var3.next();
                String name = (String)entry.getKey();
                String[] values = (String[])entry.getValue();
                int valLen = values.length;
                if(valLen == 1) {
                    retMap.put(name, values[0]);
                } else if(valLen <= 1) {
                    retMap.put(name, "");
                } else {
                    StringBuilder sb = new StringBuilder();
                    String[] var9 = values;
                    int var10 = values.length;

                    for(int var11 = 0; var11 < var10; ++var11) {
                        String val = var9[var11];
                        sb.append(",").append(val);
                    }

                    retMap.put(name, sb.toString().substring(1));
                }
            }

            return retMap;
        }
    }

}
